package com.imooc.security.app.validate.code.impl;

import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import com.imooc.security.core.validate.code.ValidateCode;
import com.imooc.security.core.validate.code.ValidateCodeException;
import com.imooc.security.core.validate.code.ValidateCodeRepository;
import com.imooc.security.core.validate.code.ValidateCodeType;

/**
 * 6.5.2 基于redis的验证码存取器，解决手机端无法使用session的问题
 */
/**
 * 6.5.3 测试访问-获取验证码：GET http://127.0.0.1:8080/code/sms?mobile=13012345678
 * HEADERS:
 * deviceId : 007
 * 
 * 6.5.4 测试访问-手机短信登录：POST http://127.0.0.1:8080/authentication/mobile
 * HEADERS:
 * Authorization : Basic aW1vb2M6aW1vb2NzZWNyZXQ= [ Basic Username imooc Password imoocsecret ]
 * Content-Type : application/x-www-form-urlencoded
 * deviceId : 007
 * BODY:
 * mobile[Text]=13012345678
 * smsCode[Text]=045378
 */
/**
 * 6.6.6 测试访问-微信社交登录
 * 【简化模式】 POST http://127.0.0.1:8080/authentication/openid
 * HEADERS:
 * Authorization : Basic aW1vb2M6aW1vb2NzZWNyZXQ= [ Basic Username imooc Password imoocsecret ]
 * Content-Type : application/x-www-form-urlencoded
 * BODY:
 * providerId[Text]=weixin
 * openId[Text]=之前登录微信存在数据库里的
 * 
 * 【授权码模式】
 * 将demo的dependency改成imooc-security-browser
 * 将8080端口改成9090/80端口，Oauth2AuthenticationService 98打断点
 * www.jeepupil.top/imooc-signIn.html，微信扫码登录。进断点后停止服务器。
 * 复制浏览器刚才的跳转连接http://www.jeepupil.top/qqLogin/weixin?code=xxxxxx&state=xxxxxx
 * 
 * 将demo的dependency改成imooc-security-app，把code交给应用服务器
 * 测试访问-APP授权码登录 http://www.jeepupil.top/qqLogin/weixin?code=xxxxxx&state=xxxxxx
 * HEADERS:
 * Authorization : Basic aW1vb2M6aW1vb2NzZWNyZXQ= [ Basic Username imooc Password imoocsecret ] // 缺少这个无法获取accessToken
 * 返回302 是因为浏览器用的是spring默认处理器，在浏览器的环境下是正确的：手机扫码后进到网站页面中。
 * APP环境下应该拿到一个令牌而不是跳转到页面。
 * core-ImoocSpringSocialConfigurer 引入processor
 * core-SocialConfig 中imoocSocialSecurityConfig()设置一下
 * app-AppSocialAuthenticationFilterPostProcessor
 */
@Component
public class RedisValidateCodeRepository implements ValidateCodeRepository {

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	
	@Override
	public void save(ServletWebRequest request, ValidateCode code, ValidateCodeType type) {
		redisTemplate.opsForValue().set(buildKey(request, type), code, 30, TimeUnit.MINUTES);
	}

	@Override
	public ValidateCode get(ServletWebRequest request, ValidateCodeType type) {
		Object value = redisTemplate.opsForValue().get(buildKey(request, type));
		if (value == null) {
			return null;
		}
		return (ValidateCode) value;
	}

	@Override
	public void remove(ServletWebRequest request, ValidateCodeType type) {
		redisTemplate.delete(buildKey(request, type));
	}

	private String buildKey(ServletWebRequest request, ValidateCodeType type) {
		String deviceId = request.getHeader("deviceId");
		if (StringUtils.isBlank(deviceId)) {
			throw new ValidateCodeException("请在请求头中携带deviceId参数");
		}
		return "code:" + type.toString().toLowerCase() + ":" + deviceId;
	}

}
